'''
Created on 15/11/2010

@author: inyaky
'''



from google.appengine.ext import db
from model.fields.uBlobTaskField import BlobTaskField
from model.fields.uDateTimeTaskField import DateTimeTaskField
from model.fields.uDeadLineTaskField import DeadLineTaskField
from model.fields.uEmailTaskField import EmailTaskField
from model.fields.uFloatTaskField import FloatTaskField
from model.fields.uIntegerTaskField import IntegerTaskField
from model.fields.uPhoneTaskField import PhoneTaskField
from model.fields.uStringTaskField import StringTaskField
from model.fields.uTextTaskField import TextTaskField
from model.uCategory import Category
import datetime
import uConst



class Task(db.Model):
    
    _owner = db.UserProperty()
    _ownerEmail = db.StringProperty()
    _parent = db.SelfReferenceProperty()
    _category = db.ReferenceProperty(Category)
    _name = db.StringProperty()
    _creationDate = db.DateTimeProperty()
    _updateDate = db.DateTimeProperty()
    _lastUpdaterUserEmail = db.StringProperty()
    _fields = db.ListProperty(db.Key)
    _sharedUsers = db.StringListProperty()
    _completed = db.BooleanProperty()
     
    def addSharedUser(self,aUserEmail):
        self._sharedUsers = self._sharedUsers + [aUserEmail]
        self.put()
    
    def _addField(self, aFieldKey):
        self._fields = self._fields + [aFieldKey.key()]
        self.put()
    
    def _createField(self, fieldName, fieldType, aReq):
        if (fieldType == uConst.BLOB_TASK_FIELD):
            aField = BlobTaskField()
        elif (fieldType == uConst.DATETIME_TASK_FIELD):
            aField = DateTimeTaskField()
        elif (fieldType == uConst.EMAIL_TASK_FIELD):
            aField = EmailTaskField()
        elif (fieldType == uConst.FLOAT_TASK_FIELD):
            aField = FloatTaskField()
        elif (fieldType == uConst.INTEGER_TASK_FIELD):
            aField = IntegerTaskField()
        elif (fieldType == uConst.PHONE_TASK_FIELD):
            aField = PhoneTaskField()
        elif (fieldType == uConst.STRING_TASK_FIELD):
            aField = StringTaskField()
        elif (fieldType == uConst.TEXT_TASK_FIELD):
            aField = TextTaskField()
        elif (fieldType == uConst.DEADLINE_TASK_FIELD):
            aField = DeadLineTaskField()
        else :
            aField = IntegerTaskField()
        aField.setTaskOwner(self.key())
        aField.setName(fieldName)
        aField.setRequired(aReq)
        aField.put()
        self._addField(aField)
        return aField
    
    def getOwner(self):
        return self._owner
    
    def setOwner(self, aOwner):
        self._owner = aOwner
        self._ownerEmail = aOwner.email()
        self.put()
    
    def getParent(self):
        return self._parent
    
    def setParent(self, aParent):
        self._parent = aParent 
        self.put()
    
    def getCategory(self):
        return self._category
    
    def setCateogry(self,aCategory):
        self._category = aCategory
        lista = self._category.getFields()
        for aTupla in lista:
            self._createField(aTupla['fName'], aTupla['fType'], aTupla['fReq'])
        self.put()
        
    def setName(self,aName):
        self._name= aName
        self.put()
    
    def getName(self):
        return self._name
    
    def getCreationDate(self):
        return self._creationDate
    
    def setCreationDate(self,aDateTime):
        self._creationDate = aDateTime
        self.put()
        
    def getUpdateDate(self):
        return self._updateDate
    
    def setUpdateDate(self,aDateTime, aUser):
        self._updateDate = aDateTime
        self._lastUpdaterUserEmail = aUser.email()
        self.put()
      
    def getSubTasks(self):
        return db.GqlQuery('SELECT * FROM Task WHERE _parent=:parent',parent=self)
    
    def getFields(self):
        return [db.get(aField) for aField in self._fields]
    
    def getFieldByName(self,name):
        for aField in self.getFields():
            if (aField.getName()==name):
                resu = aField
                break
        return resu
    
    def getFieldByKey(self,aKey):
        return db.get(aKey)
    
    def getDeadLines(self):
        return DeadLineTaskField.gql("WHERE _taskOwner=:own ORDER BY _value DESC",own=self)
    
    def ToCalendar(self):
        aux = []
        for aDeadLine in self.getDeadLines():
            aux = aux + [aDeadLine.toCalendar()]
        return aux
    
    def getNearestExpiredDeadLine(self):
        nearest = None
        for aDeadLine in self.getDeadLines():
            if not (aDeadLine.getValue()==None) and (aDeadLine.getValue()<datetime.datetime.today()):
                nearest = aDeadLine
                break
        return nearest
    
    def changeCompletedState(self):
        self._completed = not self._completed
        self.put()
        
    def getCompleted(self):
        return self._completed
        
    def toRenderable(self,includeNotEditableFields=True):
        renderableFields = []
        if includeNotEditableFields:
            renderableFields = renderableFields + [{'fname': "Usuario Creador", 'fvalue':self._ownerEmail}]
            renderableFields = renderableFields + [{'fname': "Ultimo en Modificar", 'fvalue':self._lastUpdaterUserEmail}]
            renderableFields = renderableFields + [{'fname':"Fecha de Creacion", 'fvalue':datetime.datetime.strftime(self.getCreationDate(),uConst.SWM_DATETIME_FORMAT)}]
            renderableFields = renderableFields + [{'fname':"Fecha de Actualizacion", 'fvalue':datetime.datetime.strftime(self.getUpdateDate(),uConst.SWM_DATETIME_FORMAT)}]
        for aField in self.getFields():
            renderableFields = renderableFields + aField.toRenderable()
        if (self.getNearestExpiredDeadLine()==None) or self._completed:
            hasExpired = False
            dMessage = ''
        else:
            hasExpired = True
            dMessage = self.getNearestExpiredDeadLine().getMessage()
        return [{'name':self.getName(),'key':self.key(),'fields':renderableFields, 'hasExpired':hasExpired, 'expMessage':dMessage, 'isCompleted':self.getCompleted(), 'calendarList':self.ToCalendar()}]
        
         
                
         
        
        
            
            
            
        
           
        
